package com.zf.openfeign.caller.feign;

import com.zf.openfeign.caller.entity.FileUploadEntity;
import com.zf.openfeign.caller.entity.UserInfo;
import com.zf.openfeign.caller.feign.fallback.BaseFeignClientFallbackFactory;
import feign.Response;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.cloud.openfeign.SpringQueryMap;
import org.springframework.http.MediaType;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.List;

/**
 * feign接口
 */
@FeignClient(value = "openfeign-target", path = "/base", contextId = "baseFeignClient", fallbackFactory = BaseFeignClientFallbackFactory.class)
public interface BaseFeignClient {

    /**
     * GET
     */
    @GetMapping("/hello")
    String hello(@RequestParam(name = "username", required = false) String username);

    /**
     * <pre>
     * RequestHeader 注解:
     *     1、注解Map参数时，使用Map中的 key, value 作为 请求头的名称和值
     *     2、注解String参数时，使用 @RequestHeader.name 属性的值作为请求头的名称，String参数的值作为请求头的值
     * </pre>
     */
    @GetMapping("/hello")
    String hello2(@RequestParam(name = "username", required = false) String username,
                  @RequestHeader(name = "hdMap") MultiValueMap<String, String> hdMap,
                  @RequestHeader(name = "oneHd") String oneHdxx);

    @GetMapping("/getUserInfo")
    UserInfo getUserInfo(@RequestParam(name = "username", required = false) String username,
                         @RequestParam(name = "age", required = false) Integer age);

    /**
     * SpringQueryMap 注解标识将实体类转换成 GET 参数
     */
    @GetMapping("/getUserInfo")
    UserInfo getUserInfo2(@SpringQueryMap UserInfo userInfo);

    /**
     * <pre>
     * PathVariable:
     * {username:[a-zA-Z]+}，“:” 后面可以写 “正则表达式”，这样就可以校验 “username” 的内容，只有满足表达式的内容才能正常发送请求，否则报错。
     *                          也可以不写正则校验，这样会直接发送请求。
     * </pre>
     */
    @GetMapping("/getPathVar/{username:[a-zA-Z]+}/{age}")
    UserInfo getPathVar(@PathVariable(name = "username") String username,
                        @PathVariable(name = "age") Integer age);

    /**
     * Post Json
     */
    @PostMapping("/addUserInfo")
    UserInfo addUserInfo(@RequestBody UserInfo userInfo);

    /**
     * Post "multipart/form-data" 类型的表单请求 必须指定 consumes = MediaType.MULTIPART_FORM_DATA_VALUE。
     * 使用单独的参数
     */
    @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    UserInfo uploadFile(@RequestParam("username") String username,
                        @RequestParam("age") Integer age,
                        @RequestPart("fileList") List<MultipartFile> fileList);

    /**
     * Post "multipart/form-data" 类型的表单请求 必须指定 consumes = MediaType.MULTIPART_FORM_DATA_VALUE。
     * 使用实体类
     */
    @PostMapping(value = "/uploadFile", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    UserInfo uploadFile2(FileUploadEntity fileUploadEntity);

    /**
     * 使用原始类型接收响应: 用来处理二进制内容，如文件
     */
    @GetMapping(value = "/downloadFile")
    Response downloadFile();
}
